package org.bling.parser.tags;

import java.lang.reflect.Method;
import java.util.Iterator;
import java.util.Map;

import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.bling.parser.BlingParserException;
import org.bling.parser.Node;
import org.bling.util.Util;

public class TagFactory {

	private static final Logger LOG = LogManager.getLogger(TagFactory.class);
	
	public static Tag get(Node node) {
		String pkg = Tag.class.getPackage().getName();
		String name = pkg + "." + Util.capitalize(node.getName()) + "Tag";
		try {
			Class klass = Class.forName(name);
			return get(klass, node.getAttributes());
		} catch (ClassNotFoundException e) {
			throw new RuntimeException("Can not parse tag " + node.getName()
					+ " class not found " + name);
		}

	}

	public static Tag get(Class<Tag> klass, Map<String, String> attributes) {
		try {
			Tag tag = klass.newInstance();

			if (attributes == null) {
				return tag;
			}

			Iterator<String> keys = attributes.keySet().iterator();
			while (keys.hasNext()) {
				String name = keys.next();
				String value = attributes.get(name);

				if (name == null || name.equals("") || name.length() < 2) {
					throw new BlingParserException("Invalid property [" + name
							+ "] in tag " + tag);
				}

				String method = "set" + name.substring(0, 1).toUpperCase()
						+ name.substring(1);

				Method setter = klass.getMethod(method,
						new Class[] { String.class });
				setter.invoke(tag, new Object[] { value });
				LOG.debug("property=" + name + " value=" + value);
			}

			return tag;
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException("Can't parse tag: " + klass);
		}

	}

}
